package net.lzzy.practices.service;

import net.lzzy.practices.entities.User;
import net.lzzy.practices.repositories.UserProjection;
import net.lzzy.practices.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 *
 * @author AndyStern
 */
@Service
public class UserServiceImpl implements UserService {
    private final UserRepository repository;

    @Autowired
    public UserServiceImpl(UserRepository repository) {
        this.repository = repository;
    }

    /**
     * 登录时间时检查用户名密码是否正确
     *
     * @param UserName 要检查的用户名
     * @param Password 对应密码
     * @return 检查正确则返回User对象则为null
     */
    @Override
    public User check(String UserName, String Password) {
        return repository.findUserByUserNameAndPassword(UserName,Password);
    }

    /**
     * 获取用户salt
     *
     * @param userName 该用户用户名
     * @return salt
     */
    @Override
    public String getsalt(String userName) {
        List<UserProjection> users = repository.getUsersByUserName(userName);
        if(users == null || users.size() == 0) {
            return "";
        }
        UserProjection user = users.get(0);
        String salt = user.getsalt();
        return salt == null ? "" : salt;
    }

    /**
     * 注册新用户
     *
     * @param user 前端传递的User对象
     * @return 注册成功后返回的已注册的User对象
     */
    @Override
    public User register(User user) {
        return repository.save(user);
    }

    /**
     * 判断用户名是否已存在
     *
     * @param userName 要检查的用户名
     * @return 布尔值，是否被占用
     */
    @Override
    public Boolean isUserNameOccupied(String userName) {
        return repository.countByUserName(userName) > 0;
    }

    /**
     * 获取所有用户
     *
     * @return 用户集合
     */
    @Override
    public List<User> get() {
        return repository.findAllByOrderByUpdateTimeDesc();
    }

    /**
     * 分页获取所有用户
     *
     * @param page 当前页吗
     * @param size 每页数据大小
     * @return 用户集合
     */
    @Override
    public List<User> get(int page, int size) {
        return repository.findAllByOrderByUpdateTimeDesc(PageRequest.of(page, size));
    }

    /**
     * 统计用户数量
     *
     * @return 用户数量
     */
    @Override
    public Integer count() {
        return repository.countAllBy();
    }

    /**
     * 根据关键词搜索用户
     *
     * @param kw 查询关键词
     * @return 符合条件的用户集合
     */
    @Override
    public List<User> search(String kw) {
        return repository.findByQuery(kw);
    }

    /**
     * 获取申请教师资格的用户
     *
     * @param applying true表示申请教室的用户
     * @return 符合条件的用户集合
     */
    @Override
    public List<User> getByApplyTeacher(boolean applying) {
        return repository.findUsersByApplyTeacherOrderByUpdateTimeDesc(applying);
    }

    /**
     * 审批通过教师资格
     *
     * @param id 用户id
     * @return 审批后的该用户对象
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public User approveTeacher(UUID id) {
        User user = repository.findById(id).orElse(null);
        if(user != null) {
            user.setType(User.TYPE_TEACHER);
            user.setApplyTeacher(false);
            return repository.save(user);
        }
        return null;
    }

    /**
     * 审批不通过
     *
     * @param id 用户id
     * @return 审批后的该用户对象
     */
    @Override
    public User declineTeacher(UUID id) {
        User user = repository.findById(id).orElse(null);
        if(user != null) {
            user.setApplyTeacher(false);
            return repository.save(user);
        }
        return null;
    }

    /**
     * 禁止该用户登陆
     *
     * @param id 用户id
     * @return 审批后的该用户对象
     */
    @Override
    public User banUser(UUID id) {
        User user = repository.findById(id).orElse(null);
        if(user != null && user.getType() != User.TYPE_ADMIN) {
            user.setType(User.TYPE_BANNED);
            return repository.save(user);
        }
        return null;
    }

    /**
     * 根据id获取用户
     *
     * @param id 用户id
     * @return 用户对象
     */
    @Override
    public User getById(UUID id) {
        return repository.findById(id).orElse(null);
    }
}
